﻿/************************************************************************************
* Copyright (c) 2019 All Rights Reserved.
*命名空间：Commonality.Model
*文件名： KeyenceScanningGunModel
*创建人： Liebeskind
*创建时间：2019/6/10 15:45:58
*描述:扫码命令"LON01\r\n"(4C 4F 4E 30 31 0D 0A),"01:扫码枪配置文件为01"
*       扫码命令"LON\r\n"(4C 4F 4E 30 31 0D 0A),"01:扫码枪配置文件为01"
*=====================================================================
*修改标记
*修改时间：2019/6/10 15:45:58
*修改人：Liebeskind
*描述：
************************************************************************************/
using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Timers;
using SerialPortModel;

namespace Commonality.Model.ScanningGunModel
{
    /// <summary>
    /// 数据接收方法委托
    /// </summary>
    /// <param name="code"></param>
    public delegate void QRcodeReceiveDelegate(ref string code);
    public class CKeyenceScanningGunModel
    {
        #region 串口参数
        public string portName { get; set; }
        public int baudRate { get; set; }
        public int dataBits { get; set; }
        public Parity parity { get; set; }
        public StopBits stopBits { get; set; }
        #endregion
        #region 网口参数

        #endregion
        #region 通讯设备实例
        private CSerialPortModel serialPort;
        #endregion
        #region 超时
        private Timer timerTOA;
        /// <summary>
        /// 超时标志
        /// </summary>
        public bool TOAFlag = false;
        #endregion
        #region 命令
        /// <summary>
        /// 开启扫码命令
        /// </summary>
        //private static byte[] OnScanCodeOrder = new byte[] { 0x4C, 0x4F, 0x4E, 0x30, 0x31, 0x0D, 0x0A };
        private static byte[] OnScanCodeOrder = new byte[] { 0x4C, 0x4F, 0x4E, 0x0D};
        /// <summary>
        /// 关闭扫码命令
        /// </summary>
        private static byte[] OffScanCodeOrder = new byte[] { 0x4C, 0x4F, 0x46, 0x46, 0x0D};
        #endregion
        #region 装置状态
        /// <summary>
        /// 连接状态
        /// </summary>
        public bool Connection { get; set; }
        #endregion
        #region 原始返回值
        /// <summary>
        /// 原始返回值
        /// </summary>
        public string ResultData { get; set; }
        #endregion

        private DataReceived dataReceived;
        private QRcodeReceiveDelegate QRcodeReceiveDelegate;
        private event QRcodeReceiveDelegate QRcodeReceiveEvent;
        /// <summary>
        /// 扫码枪设备类
        /// 1.扫码超时回调返回字符"Timeouts";
        /// </summary>
        /// <param name="portName"></param>
        /// <param name="baudRate"></param>
        /// <param name="dataBits"></param>
        /// <param name="parity"></param>
        /// <param name="stopBits"></param>
        /// <param name="QRcodeReceive"></param>
        public CKeyenceScanningGunModel(string portName, int baudRate, int dataBits, Parity parity, StopBits stopBits,QRcodeReceiveDelegate QRcodeReceive)
        {
            #region 串口资源
            this.portName = portName;
            this.baudRate = baudRate;
            this.dataBits = dataBits;
            this.parity = parity;
            this.stopBits = stopBits;

            serialPort = new CSerialPortModel(this.portName, this.baudRate, this.dataBits, this.parity, this.stopBits);
            this.Connection = serialPort.Open();
            #endregion

            #region 内部接收数据处理事件
            dataReceived = new DataReceived(ReturnedDataAnalyse);
            serialPort.SetDataReceived(dataReceived);
            #endregion

            #region 接收委托
            QRcodeReceiveDelegate = new QRcodeReceiveDelegate(QRcodeReceive);
            QRcodeReceiveEvent += QRcodeReceiveDelegate;
            #endregion

            #region 超时定时器资源
            timerTOA = new Timer();
            timerTOA.AutoReset = false;
            timerTOA.Enabled = false;
            timerTOA.Elapsed += new ElapsedEventHandler(TOA);
            #endregion

        }
        public string ScanCode()
        {
            if (serialPort.IsOpen())
            {
                serialPort.SendData(OnScanCodeOrder);
                ResultData = "";
                return "Trigger";
            }
            else
            {
                return "Lost Connection";
            }
        }
        /// <summary>
        /// 带超时的询问
        /// </summary>
        /// <param name="interval">超时时间ms</param>
        /// <returns></returns>
        public string ScanCodeTimeout(double interval)
        {
            if (serialPort.IsOpen())
            {
                serialPort.SendData(OnScanCodeOrder);
                timerTOA.Interval = interval;
                TOAFlag = false;
                timerTOA.Stop();
                timerTOA.Start();
                ResultData = "";
                return "Trigger";
            }
            else
            {
                return "Lost Connection";
            }
        }
        public string OffScanCode()
        {
            if (serialPort.IsOpen())
            {
                serialPort.SendData(OffScanCodeOrder);
                ResultData = "";
                return "Off";
            }
            else
            {
                return "Lost Connection";
            }
        }
        public string Reconnect()
        {
            if (serialPort.IsOpen())
            {
                this.Connection = true;
                return "Connected";
            }
            else
            {
                serialPort.Close();
                serialPort = new CSerialPortModel(this.portName, this.baudRate, this.dataBits, this.parity, this.stopBits);
                serialPort.Open();
                return "Attempt Reconnect";
            }

        }


        #region 私有方法
        private void QRcodeReceiveEventFunction(ref string code)
        {
            if (QRcodeReceiveEvent != null)
            {
                QRcodeReceiveEvent(ref code);
            }
            ResultData = code;
        }
        /// <summary>
        /// 接收数据处理方法
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ReturnedDataAnalyse(object sender, SerialDataReceivedEventArgs e)
        {
            System.Threading.Thread.Sleep(5);
            int size = (sender as SerialPort).BytesToRead;
            byte[] QRCodeByte = new byte[size];
            (sender as SerialPort).Read(QRCodeByte, 0, size);
            (sender as SerialPort).DiscardInBuffer();
            //           
            string code = Encoding.ASCII.GetString(QRCodeByte);
            QRcodeReceiveEventFunction(ref code);
            //
            timerTOA.Stop();
            TOAFlag = false;
        }
        /// <summary>
        /// 超时到方法
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void TOA(Object sender, EventArgs e)
        {
            timerTOA.Stop();
            TOAFlag = true;
            string message = "Timeouts";
            QRcodeReceiveEventFunction(ref message);
            OffScanCode();
        }
        #endregion

    }
}
